﻿#include "AlgorithmManager.h"
#include <QPluginLoader>
#include <QCoreApplication>
#include <QDir>
#include "component_log.h"

AlgorithmManager::AlgorithmManager(QObject* parent)
	: ComponentBase(parent)
{
	m_name = u8"算法管理组件";
	m_type = Component::component_algorithm;
	m_algMap.clear();
}

AlgorithmManager::~AlgorithmManager()
{}

// 加载普通算法
bool AlgorithmManager::ReadAlgPlugin(const QString& path)
{
	QString dir = path + "algorithm/";
	QDir d(dir);
	QStringList files = d.entryList({ "*.dll" }, QDir::Files);
	for (auto& f : files) {
		QPluginLoader load(dir + f);
		if (!load.load()) {
			log_error("{} plugin loade faied, err = {}", f, load.errorString());
			continue;
		}
		AlgorithmPlugin* temp = qobject_cast<AlgorithmPlugin*>(load.instance());
		if (temp == nullptr) {
			log_trace("{} plugin not case to alg plugin", f);
			continue;
		}
		QJsonObject data = load.metaData();
		QString iid = data["IID"].toString();
		if (iid.isEmpty()) {
			log_error("{} not contians IID", f);
			continue;
		}
		log_trace("{} IID = {}", iid);
		QString name = iid.split('.').last();
		m_algMap.emplace(name, temp);
	}
	return true;
}

// 加载视觉算法
bool AlgorithmManager::ReadVisualALgPlugin(const QString& path)
{
	QString dir = path + "unstack/";
	QDir d(dir);
	QStringList files = d.entryList({ "*.dll" }, QDir::Files);
	for (auto& f : files) {
		QPluginLoader load(dir + f);
		if (!load.load()) {
			log_error("{} plugin loade faied, err = {}", f, load.errorString());
			continue;
		}
		AlgorithmVisualPulgin* temp = qobject_cast<AlgorithmVisualPulgin*>(load.instance());
		if (temp == nullptr) {
			log_trace("{} plugin not case to alg plugin", f);
			continue;
		}
		QJsonObject data = load.metaData();
		QString iid = data["IID"].toString();
		if (iid.isEmpty()) {
			log_error("{} not contians IID", f);
			continue;
		}
		log_trace("{} IID = {}", iid);
		QString name = iid.split('.').last();
		m_visAlgMap.emplace(name, temp);
	}
	return true;
}


// 组件初始化处理函数
int AlgorithmManager::ComponentInit()
{
	log_trace("Start load Algorithm");
	QString dir = QCoreApplication::applicationDirPath();
	dir = QDir(dir).absolutePath();

	if (!dir.endsWith('/') && !dir.endsWith('\\')) {
		dir.append('/');
	}
	ReadAlgPlugin(dir);
	ReadVisualALgPlugin(dir);

	log_trace("load finish, alg num ={}", m_algMap.size());
	return 0;
}

/*自检接口*/
bool AlgorithmManager::ComponentCheckSelfState()
{
	return true;
}
/*复位接口*/
bool AlgorithmManager::ComponentSelfReset()
{
	return true;
}

bool AlgorithmManager::ExcuteCmd(int cmd, const QByteArray& input, QByteArray& output)
{
	if (cmd == 1) {	// 获取加载的算法名称
		QStringList names = GetAllAlgName();
		output.clear();
		output = (names.join('-').toUtf8());
		return true;
	}

	if (cmd == 2) {	// 获取加载的视觉算法名称
		QStringList names = GetAllVisAlgName();
		output.clear();
		output = (names.join('-').toUtf8());
		return true;
	}

	return false;
}


QStringList AlgorithmManager::GetAllAlgName()
{
	QStringList out;
	for (auto& iter : m_algMap) {
		out.append(iter.first);
	}

	return out;
}

Algorithm* AlgorithmManager::GetAlgObjectByName(const QString& name)
{
	auto iter = m_algMap.find(name);
	if (iter != m_algMap.end()) {
		return m_algMap[name]->CreateAlgorithmObject();
	}

	return nullptr;
}

QStringList AlgorithmManager::GetAllVisAlgName()
{
	QStringList out;
	for (auto& iter : m_visAlgMap) {
		out.append(iter.first);
	}

	return out;
}

AlgorithmVisual* AlgorithmManager::GetVisAlgObjectByName(const QString& name)
{
	auto iter = m_visAlgMap.find(name);
	if (iter != m_visAlgMap.end()) {
		return m_visAlgMap[name]->CreateAlgorithm();
	}

	return nullptr;
}
